/* 
** (Copyright) sejishikong <sejishikong@263.net>
** Authors:    sejishikong <sejishikong@263.net>
**             Wei Lian <lianwei2003.student@sina.com> 
** Maintainer: Wei Lian
**    This program is free software; you can redistribute it and/or modify
**    it under the terms of the GNU General Public License Version 2 as
**    published by the Free Software Foundation;
**
**    This program is distributed in the hope that it will be useful,
**    but WITHOUT ANY WARRANTY; without even the implied warranty of
**    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
**    GNU General Public License for more details.
**
**    You should have received a copy of the GNU General Public License
**    along with this program; if not, write to the Free Software
**    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
**
*/

#include "sys.h"
#include <sys/soundcard.h>
#include <sys/ioctl.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/time.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>

Sys::Sys ()
{
  if ((sound_handle = open ("/dev/mixer", O_RDWR, 0)) == -1)
    {
      ::perror ("/dev/mixer");
    }
}

Sys::~Sys ()
{
  ::close (sound_handle);
}


int
Sys::sound_read ()
{
  int result;
  if (::ioctl (sound_handle, MIXER_READ (4), &result) == -1)
    {
      perror ("read_error");
      return -1;
    }
  result = ((result >> 8) + (result & 0xFF)) >> 1;
  result = (result > 0) ? result : 0;
  result = (result < 100) ? result : 100;
  return result;
}

void
Sys::sound_write (int leftright)
{
  leftright = (leftright < 0) ? 0 : leftright;
  leftright = (leftright > 100) ? 100 : leftright;
  leftright = (leftright << 8) | (leftright & 0xFF);
  if (::ioctl (sound_handle, MIXER_WRITE (4), &leftright) == -1)
    {
      perror ("write_error");
      return;
    }
}

int
Sys::connect_to_server (char *host, int portnum)
{
  int sock;
  struct sockaddr_in serv_addr;
  struct hostent *server;

  sock =::socket (AF_INET, SOCK_STREAM, 0);
  if (sock == -1)
    {
      perror ("ERROR opening socket");
      return -3;
    }
  server =::gethostbyname (host);
  if (server == NULL)
    {
      perror ("ERROR, no such host");
      close (sock);
      return -2;
    }
  ::memset ((char *) &serv_addr, 0, sizeof (serv_addr));
  serv_addr.sin_family = AF_INET;
  ::memcpy ((char *) &serv_addr.sin_addr.s_addr,
	    (char *) server->h_addr, server->h_length);
  serv_addr.sin_port = htons (portnum);

//  int flags = fcntl (sock, F_GETFL, 0);
//  fcntl (sock, F_SETFL, flags | O_NONBLOCK);
  if (::connect
      (sock, (struct sockaddr *) &serv_addr, sizeof (serv_addr)) == -1)
    {
      ::close (sock);
      return -1;
    }
  return sock;
}
